// Copyright (C) 1953-2022 NUDT
// Verilog module name - packet_output_control 
// Version: V4.1.0.0.20230103
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//          
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module packet_output_control
(
        i_clk  ,
        i_rst_n,                
        
        iv_fifo_usedw ,
        o_fifo_rd     ,
        iv_fifo_rdata ,
        
        ov_data       ,
        o_data_wr     ,
        i_data_ready        
);

// I/O
// clk & rst
input                  i_clk;   
input                  i_rst_n;
//
(*MARK_DEBUG="true"*)input       [4:0]      iv_fifo_usedw;
(*MARK_DEBUG="true"*)output reg             o_fifo_rd    ;
(*MARK_DEBUG="true"*)input       [8:0]      iv_fifo_rdata; 
// transmit pkt to phy     
(*MARK_DEBUG="true"*)output  reg [8:0]      ov_data     ;
(*MARK_DEBUG="true"*)output  reg            o_data_wr   ;
                     input                  i_data_ready;
//***************************************************
//                   fifo read
//***************************************************
reg         [2:0]       rv_poc_state;
// internal reg&wire
localparam  idle_s            = 3'd0,
            output_1st_data_s = 3'd1,
            output_data_s     = 3'd2,
            wait_ready_s      = 3'd3;
            
always@(posedge i_clk or negedge i_rst_n)begin
    if(!i_rst_n) begin
        ov_data                   <= 9'b0;
        o_data_wr                 <= 1'b0;
        
        o_fifo_rd                 <= 1'b0;
        rv_poc_state          <= idle_s;
    end
    else begin
        case(rv_poc_state)
            idle_s:begin
                ov_data                   <= 9'b0;
                o_data_wr                 <= 1'b0;
                if(iv_fifo_usedw == 5'd13)begin//至少��?13，否则出现fifo读空问题.
                    o_fifo_rd             <= 1'b1;
                    rv_poc_state      <= output_1st_data_s;
                end 
                else begin
                    o_fifo_rd                 <= 1'b0;
                    rv_poc_state          <= idle_s;
                end
            end
            output_1st_data_s:begin
                ov_data               <= iv_fifo_rdata;
                o_data_wr             <= 1'b1;  
                
                o_fifo_rd             <= 1'b1;
                rv_poc_state      <= output_data_s;            
            end
            output_data_s:begin
                ov_data               <= iv_fifo_rdata;
                o_data_wr             <= 1'b1;  
                if(i_data_ready)begin    
                    if(iv_fifo_rdata[8])begin//tail.
                        o_fifo_rd                 <= 1'b0;                  
                        rv_poc_state          <= idle_s;
                    end
                    else begin
                        o_fifo_rd                 <= 1'b1;                   
                        rv_poc_state          <= output_data_s;
                    end
                end
                else begin
                    o_fifo_rd                 <= 1'b0;
                    if(iv_fifo_rdata[8])begin//tail.
                        rv_poc_state          <= idle_s;
                    end
                    else begin
                        rv_poc_state          <= wait_ready_s;
                    end
                end                
            end
            wait_ready_s:begin
                ov_data                   <= 9'b0;
                o_data_wr                 <= 1'b0;
                if(i_data_ready)begin
                    o_fifo_rd                 <= 1'b1;
                    rv_poc_state          <= output_data_s;                    
                end
                else begin
                    o_fifo_rd                 <= 1'b0;
                    rv_poc_state          <= wait_ready_s;                    
                end                
            end
            default:begin
                ov_data                   <= 9'b0;
                o_data_wr                 <= 1'b0;
                
                o_fifo_rd                 <= 1'b0;
                rv_poc_state          <= idle_s;            
            end
        endcase 
    end
end
endmodule